home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / diskBoot.OpenProm / fs.c < prev    next >
C/C++ Source or Header  |  1991-01-14  |  9KB  |  328 lines

  1. /* fs.c -
  2.  *
  3.  *    General filesystem support.
  4.  *
  5.  * Copyright (C) 1985 Regents of the University of California
  6.  * All rights reserved.
  7.  */
  8.  
  9. #ifdef notdef
  10. static char rcsid[] = "$Header: /sprite/src/boot/sunOpenProm/RCS/fs.c,v 1.12 91/01/06 00:18:12 dlong Exp $ SPRITE (Berkeley)";
  11. #endif not lint
  12.  
  13. #include "sprite.h"
  14. #include "fsBoot.h"
  15. #include "ofs.h"
  16.  
  17. /*
  18.  * For non-block aligned reads.
  19.  */
  20. char    readBuffer[FS_BLOCK_SIZE];
  21.  
  22. /*
  23.  * For lookup
  24.  */
  25. static char    component[FS_MAX_NAME_LENGTH];
  26.  
  27. /*
  28.  * Forward declarations.
  29.  */
  30. void FsGetFileDesc();
  31. void FsInitFileHandle();
  32.  
  33. /*
  34.  * ----------------------------------------------------------------------------
  35.  *
  36.  * Open --
  37.  *
  38.  *    Open a file.  This does a simple lookup (based on the kernel's
  39.  *    FsLocalLookup) and creates a handle for the file.
  40.  *
  41.  * Results:
  42.  *    SUCCESS or a return code from various sub-operations.
  43.  *
  44.  * Side effects:
  45.  *    Calls malloc
  46.  *
  47.  * ----------------------------------------------------------------------------
  48.  */
  49.  
  50. ReturnStatus
  51. Open(fileName, useFlags, permissions, handlePtrPtr)
  52.     char *fileName;
  53.     int useFlags;
  54.     int permissions;
  55.     Fsio_FileIOHandle     **handlePtrPtr;
  56. {
  57.     register ReturnStatus status;
  58.     Fsio_FileIOHandle *curHandlePtr;
  59.     register char *curCharPtr;
  60.     register char *componentPtr;
  61.     register int index;
  62.  
  63.     curCharPtr = fileName;
  64.     while(*curCharPtr == '/') {
  65.     curCharPtr++;
  66.     }
  67.     curHandlePtr = fsRootHandlePtr;
  68.  
  69.     while (*curCharPtr != '\0') {
  70.     if (curHandlePtr->descPtr->fileType != FS_DIRECTORY) {
  71.         return(FS_NOT_DIRECTORY);
  72.     }
  73.         /*
  74.          * Get the next component.
  75.          */
  76.         index = 0;
  77.     componentPtr = component;
  78.         while (*curCharPtr != '/' && *curCharPtr != '\0') {
  79.             *componentPtr++ = *curCharPtr++;
  80.         }
  81.         *componentPtr = '\0';
  82. #ifndef NO_PRINTF
  83.     Mach_MonPrintf(" %s ", component);
  84. #endif
  85.         /*
  86.          * Skip intermediate and trailing slashes so that *curCharPtr
  87.          * is Null when 'component' has the last component of the name.
  88.          */
  89.         while (*curCharPtr == '/') {
  90.             curCharPtr++;
  91.         }
  92.  
  93.     status = FsFindComponent(fsDomainPtr, curHandlePtr, component,
  94.                           &curHandlePtr);
  95.  
  96.     if (status != SUCCESS) {
  97. #ifndef NO_PRINTF
  98.         Mach_MonPrintf("<%x>\n", status);
  99. #endif
  100.         return(status);
  101.     }
  102.     }
  103.     *handlePtrPtr = curHandlePtr;
  104.     return status;
  105. }
  106.  
  107. /*
  108.  * ----------------------------------------------------------------------------
  109.  *
  110.  * Read --
  111.  *
  112.  *    Read from a file given its handle.
  113.  *
  114.  * Results:
  115.  *    A return status from the read.
  116.  *
  117.  * Side effects:
  118.  *    buffer is loaded with the data read in.
  119.  *    *readCountPtr is updated to reflect the number of bytes read.
  120.  *
  121.  * ----------------------------------------------------------------------------
  122.  */
  123. ReturnStatus
  124. Read(handlePtr, offset, numBytes, buffer, readCountPtr)
  125.     register Fsio_FileIOHandle     *handlePtr;
  126.     int            offset;
  127.     int            numBytes;
  128.     register Address    buffer;
  129.     int            *readCountPtr;
  130. {
  131.     int                firstBlock;
  132.     int                lastBlock;
  133.     int                lastByte;
  134.     BlockIndexInfo        indexInfo;
  135.     register    int        readSize;
  136.     register    int        blockAddr;
  137.     register    int        blockOffset;
  138.     register    int        bufferIndex;
  139.     register     ReturnStatus    status;
  140.     register    int        size;
  141.  
  142.     firstBlock = offset / FS_BLOCK_SIZE; 
  143.     lastByte = offset + numBytes - 1;
  144.     if (lastByte > handlePtr->descPtr->lastByte) {
  145.     lastByte = handlePtr->descPtr->lastByte;
  146.     }
  147.     lastBlock = lastByte / FS_BLOCK_SIZE;
  148.  
  149.     (void)FsGetFirstIndex(handlePtr, firstBlock, &indexInfo);
  150.  
  151.     bufferIndex = 0;
  152.     blockOffset = offset & FS_BLOCK_OFFSET_MASK;
  153. #ifdef SCSI0_BOOT 
  154.     Mach_MonPrintf(" read %d at %d into %x\n", numBytes, offset, buffer);
  155. #endif 
  156.  
  157.     while (indexInfo.blockNum <= lastBlock) {
  158.     if (indexInfo.blockNum < lastBlock) {
  159.         size = FS_BLOCK_SIZE - blockOffset;
  160.         readSize = FS_BLOCK_SIZE;
  161.     } else {
  162.         size = (lastByte & FS_BLOCK_OFFSET_MASK) + 1 - blockOffset;
  163.         readSize = size;
  164.     }
  165.     blockAddr = *indexInfo.blockAddrPtr + 
  166.     ((Ofs_DomainHeader *) fsDomainPtr->clientData)->dataOffset *
  167.         FS_FRAGMENTS_PER_BLOCK;
  168.     if (blockOffset != 0 || size != FS_BLOCK_SIZE) { 
  169.         status = FsDeviceBlockIO(FS_READ, &fsDevice,
  170.         blockAddr + blockOffset / FS_FRAGMENT_SIZE,
  171.         (readSize - 1) / FS_FRAGMENT_SIZE + 1, readBuffer);
  172.         if (status != SUCCESS) {
  173.         goto readError;
  174.         }
  175.         bcopy(&readBuffer[blockOffset % FS_FRAGMENT_SIZE],
  176.         &buffer[bufferIndex], size);
  177.     } else {
  178.         status = FsDeviceBlockIO(FS_READ, &fsDevice, blockAddr,
  179.         FS_FRAGMENTS_PER_BLOCK, &(buffer[bufferIndex]));
  180.         if (status != SUCCESS) {
  181.         goto readError;
  182.         }
  183.     }
  184.     bufferIndex += size;
  185.     blockOffset = 0;
  186.     FsGetNextIndex(handlePtr, &indexInfo);
  187.     }
  188.  
  189. readError:
  190.  
  191.     *readCountPtr = bufferIndex;
  192.  
  193.     return(status);
  194. }
  195.  
  196. /*
  197.  *----------------------------------------------------------------------
  198.  *
  199.  * FsFindComponent --
  200.  *
  201.  *
  202.  * Results:
  203.  *    None.
  204.  *
  205.  * Side effects:
  206.  *
  207.  *----------------------------------------------------------------------
  208.  */
  209. ReturnStatus
  210. FsFindComponent(domainPtr, curHandlePtr, component, newHandlePtrPtr)
  211.     Fsdm_Domain *domainPtr;
  212.     Fsio_FileIOHandle *curHandlePtr;
  213.     char *component;
  214.     Fsio_FileIOHandle **newHandlePtrPtr;
  215. {
  216.     register ReturnStatus status;
  217.     register int dirOffset;        /* Offset within the directory */
  218.     register int blockOffset;        /* Offset within a directory block */
  219.     register Fslcl_DirEntry *dirEntryPtr;    /* Reference to directory entry */
  220.     int length;                /* Length variable for read call */
  221.     register Fsio_FileIOHandle *handlePtr;
  222.  
  223.     dirOffset = 0;
  224.     do {
  225.     length = FSLCL_DIR_BLOCK_SIZE;
  226.     status = Read(curHandlePtr, dirOffset, length, readBuffer, &length);
  227.     if (status != SUCCESS) {
  228.         return(status);
  229.     }
  230.     if (length == 0) {
  231.         return(FS_FILE_NOT_FOUND);
  232.     }
  233.     dirEntryPtr = (Fslcl_DirEntry *)readBuffer;
  234.     blockOffset = 0;
  235.     while (blockOffset < FSLCL_DIR_BLOCK_SIZE) {
  236.         dirEntryPtr = (Fslcl_DirEntry *)((int)readBuffer + blockOffset);
  237.         if (dirEntryPtr->fileNumber != 0) {
  238.         /*
  239.          * A valid directory record.
  240.          */
  241. #ifndef NO_PRINTF
  242.         Mach_MonPrintf("Found %s\n", dirEntryPtr->fileName);
  243. #endif NO_PRINTF
  244.         if (strcmp(component, dirEntryPtr->fileName) == 0) {
  245.             handlePtr = (Fsio_FileIOHandle *)malloc(sizeof(Fsio_FileIOHandle));
  246.             FsInitFileHandle(domainPtr, dirEntryPtr->fileNumber,
  247.                     handlePtr);
  248.             *newHandlePtrPtr = handlePtr;
  249.             return(SUCCESS);
  250.         }
  251.         }
  252.         blockOffset += dirEntryPtr->recordLength;
  253.     }
  254.     dirOffset += FSLCL_DIR_BLOCK_SIZE;
  255.     } while(TRUE);
  256. }
  257.  
  258. /*
  259.  *----------------------------------------------------------------------
  260.  *
  261.  * FsInitFileHandle --
  262.  *
  263.  *    Initialize a file handle.
  264.  *
  265.  * Results:
  266.  *    None.
  267.  *
  268.  * Side effects:
  269.  *    Fills in the file handle that our caller has already allocated.
  270.  *
  271.  *----------------------------------------------------------------------
  272.  */
  273. void
  274. FsInitFileHandle(domainPtr, fileNumber, handlePtr)
  275.     Fsdm_Domain *domainPtr;
  276.     int fileNumber;
  277.     register Fsio_FileIOHandle *handlePtr;
  278. {
  279.     register Fsdm_FileDescriptor *descPtr;
  280.  
  281.     bzero((Address)handlePtr, sizeof(Fsio_FileIOHandle));
  282.     handlePtr->hdr.fileID.minor = fileNumber;
  283.     descPtr = (Fsdm_FileDescriptor *)malloc(sizeof(Fsdm_FileDescriptor));
  284.     FsGetFileDesc(domainPtr, fileNumber, descPtr);
  285.     handlePtr->descPtr = descPtr;
  286. }
  287.  
  288. /*
  289.  *----------------------------------------------------------------------
  290.  *
  291.  * FsGetFileDesc --
  292.  *
  293.  *    Read in a file descriptor from the disk.
  294.  *
  295.  * Results:
  296.  *    None.
  297.  *
  298.  * Side effects:
  299.  *    Fills in the file descriptor that our caller has already allocated.
  300.  *
  301.  *----------------------------------------------------------------------
  302.  */
  303. void
  304. FsGetFileDesc(domainPtr, fileNumber, descPtr)
  305.     Fsdm_Domain *domainPtr;
  306.     register int fileNumber;
  307.     register Fsdm_FileDescriptor *descPtr;
  308. {
  309.     register Ofs_DomainHeader *headerPtr;
  310.     register int         blockNum;
  311.     register int         offset;
  312.  
  313.     headerPtr = ((Ofs_DomainHeader *) domainPtr->clientData);
  314.     blockNum = headerPtr->fileDescOffset + fileNumber / FSDM_FILE_DESC_PER_BLOCK;
  315.     offset = (fileNumber & (FSDM_FILE_DESC_PER_BLOCK - 1)) *
  316.         FSDM_MAX_FILE_DESC_SIZE;
  317.  
  318.     (void)FsDeviceBlockIO(FS_READ, &fsDevice, 
  319.                blockNum * FS_FRAGMENTS_PER_BLOCK,
  320.                FS_FRAGMENTS_PER_BLOCK, readBuffer);
  321.     bcopy( readBuffer + offset, (char *) descPtr, sizeof(Fsdm_FileDescriptor));
  322. #ifndef NO_PRINTF
  323.     if (descPtr->magic != FSDM_FD_MAGIC) {
  324.     Mach_MonPrintf("desc %d bad <%x>\n", fileNumber, descPtr->magic);
  325.     }
  326. #endif
  327. }
  328.